from typing import List

from elasticsearch import AsyncElasticsearch



class ESClient:

    def __init__(self, core_client: AsyncElasticsearch):
        self.client = core_client

    async def create(self, index, id, *, body, **kwargs):
        """
            创建文档，如果文档已经存在，则返回409错误
        """
        from common.g.g import G_LOGGER
        res = await self.client.create(index, id, body=body, **kwargs)
        G_LOGGER.info(res)
        return res

    async def index(self, index, id, *, body, **kwargs):
        res = await self.client.index(index, id=id, body=body, **kwargs)
        return res

    async def search(self, index, query, **kwargs):
        """
        {
            'took': 1,
            'timed_out': False,
            '_shards': {
                'total': 1,
                'successful': 1,
                'skipped': 0,
                'failed': 0
            },
            'hits': {
                'total': {
                    'value': 0,
                    'relation': 'eq'
                },
                'max_score': None,
                'hits': []
                }
            }
        Args:
            index:
            query:
            **kwargs:

        Returns:
        """
        res = await self.client.search(index=index, body=query, **kwargs)
        if "highlight" in query and res.get("_shards", {}).get("successful") == 1:
            res_list = res["hits"]["hits"]
            return res_list
        return res

    def __getattr__(self, attr):
        return getattr(self.client, attr)


class SPUESClient(ESClient):

    async def create_product_index(self):
        """
        成功：
            {'_index': 'index_spu', '_type': '_doc', '_id': '5WsM44QBbOP0ZlXZvSGc',
            '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0},
            '_seq_no': 0, '_primary_term': 1}
        Returns:

        """
        index = "index_spu"
        body = {
            "mappings": {
                "properties": {
                    "mall_id": {"type": "integer"},
                    "id": {"type": "integer"},
                    "name": {"type": "text", "analyzer": "ik_max_word", "index": True},
                    "alias": {"type": "text", "analyzer": "ik_max_word", "index": True},
                    "spu_type": {"type": "integer"},
                    "onsale": {"type": "integer"},
                    "start_timestamp": {"type": "integer"},
                    "end_timestamp": {"type": "integer"}
                }
            }
        }
        res = await self.client.index(index, body=body)
        return res

    async def search_id(self, index, query, _source: List[str] = None, **kwargs):
        """
        {
            'took': 260,
            'timed_out': False,
            '_shards': {
                'total': 1,
                'successful': 1,
                'skipped': 0,
                'failed': 0
            },
            'hits': {
                'total': {
                    'value': 1,
                    'relation': 'eq'
                },
                'max_score': 0.5753642,
                'hits': [
                    {
                        '_index': 'index_spu',
                        '_type': '_doc',
                        '_id': '100000000',
                        '_score': 0.5753642,
                        '_source': {
                            'id': 100000000
                        }
                    }
                ]
            }
        }
        Args:
            index:
            query:
            _source:
            **kwargs:

        Returns:

        """
        res = await self.client.search(index=index, body=query, _source=_source, **kwargs)
        data = res.get("hits", {}).get("hits", [])
        return [i["_source"]["id"] for i in data]


if __name__ == '__main__':
    import asyncio

    es_config = {
        "hosts": ["http://localhost:9200"]
    }


    async def test():
        client = AsyncElasticsearch(**es_config)
        pclient = SPUESClient(client)
        res = await pclient.create_product_index()
        query = {
            "query": {
                "match": {
                    "name": "商"
                }
            }
        }
        res = await pclient.search_id("index_spu", query=query, _source=["id"])
        print(res)
        await client.close()

    asyncio.run(test())
